'use strict';

const Service = require('egg').Service;
const BaseService = require('./base');
const City = require('../model/city');
const { Op } = require('sequelize');

class CityService extends Service {
  constructor(ctx) {
    super(ctx);
    this.base = new BaseService(ctx, City);
  }

  /**
   * 获取城市列表（支持分页、搜索、排序、标签筛选）
   * @param {Object} options - 查询选项
   * @param {number} options.page - 页码
   * @param {number} options.pageSize - 每页数量
   * @param {string} options.keyword - 搜索关键词
   * @param {string} options.tag - 标签筛选
   * @param {string} options.sortBy - 排序字段
   * @param {string} options.sortOrder - 排序方式 (asc/desc)
   */
  async getList(options = {}) {
    const {
      page = 1,
      pageSize = 10,
      keyword,
      tag,
      sortBy = 'created_at',
      sortOrder = 'desc',
    } = options;

    const offset = (page - 1) * pageSize;
    const limit = pageSize;

    // 构建查询条件
    const where = {};

    // 关键词搜索（搜索城市名称和描述）
    if (keyword && keyword.trim()) {
      where[Op.or] = [
        { name: { [Op.like]: `%${keyword.trim()}%` } },
        { description: { [Op.like]: `%${keyword.trim()}%` } },
      ];
    }

    // 标签筛选（检查tags字段中是否包含指定标签）
    if (tag && tag.trim()) {
      where.tags = { [Op.like]: `%${tag.trim()}%` };
    }

    // 排序配置
    const orderField = this.validateSortField(sortBy);
    const orderDirection = sortOrder.toLowerCase() === 'asc' ? 'ASC' : 'DESC';

    try {
      // 查询数据
      const { count, rows } = await City.findAndCountAll({
        where,
        order: [[orderField, orderDirection]],
        offset,
        limit,
      });

      const list = rows.map(city => this.toDTO(city));

      return {
        list,
        page,
        pageSize,
        total: count,
        totalPages: Math.ceil(count / pageSize),
      };
    } catch (error) {
      this.ctx.logger.error('查询城市列表失败:', error);
      throw error;
    }
  }

  /**
   * 验证并返回有效的排序字段
   */
  validateSortField(sortBy) {
    const validFields = [
      'id',
      'name',
      'rating',
      'views',
      'recommendations',
      'created_at',
      'updated_at',
    ];

    return validFields.includes(sortBy) ? sortBy : 'created_at';
  }

  // 列表（保留用于兼容性）
  async list() {
    const rows = await this.base.list();
    return rows.map(this.toDTO);
  }

  // 详情
  async getById(id) {
    const city = await this.base.findById(id);
    if (!city) return null;
    return this.toDTO(city);
  }

  // 创建
  async create(payload) {
    const data = this.toModel(payload);
    const created = await this.base.create(data);
    return this.toDTO(created);
  }

  // 更新
  async update(id, payload) {
    const data = this.toModel(payload);
    const affected = await this.base.updateById(id, data);
    if (!affected) return null;
    const updated = await this.base.findById(id);
    return this.toDTO(updated);
  }

  // 删除
  async remove(id) {
    const affected = await this.base.deleteById(id);
    return affected > 0;
  }

  /**
   * 批量删除
   * @param {Array<number>} ids - 城市ID数组
   */
  async batchRemove(ids) {
    try {
      const result = await City.destroy({
        where: {
          id: {
            [Op.in]: ids,
          },
        },
      });
      return result; // 返回删除的数量
    } catch (error) {
      this.ctx.logger.error('批量删除城市失败:', error);
      throw error;
    }
  }

  /**
   * 增加推荐数
   * @param {number} id - 城市ID
   */
  async incrementRecommendations(id) {
    try {
      const city = await City.findByPk(id);
      if (!city) {
        return {
          success: false,
          message: '城市不存在'
        };
      }

      // 推荐数+1
      await city.update({
        recommendations: (city.recommendations || 0) + 1
      });

      return {
        success: true,
        data: this.toDTO(city)
      };
    } catch (error) {
      this.ctx.logger.error('增加推荐数失败:', error);
      throw error;
    }
  }

  // 入库模型转换
  toModel(payload) {
    const model = {};

    // 只添加实际传入的字段
    if (payload.name !== undefined) model.name = payload.name;
    if (payload.description !== undefined) model.description = payload.description;
    if (payload.image !== undefined) model.image = payload.image;
    if (payload.tags !== undefined) {
      model.tags = Array.isArray(payload.tags) ? JSON.stringify(payload.tags) : payload.tags;
    }
    if (payload.rating !== undefined) model.rating = payload.rating;
    if (payload.views !== undefined) model.views = payload.views;
    if (payload.recommendations !== undefined) model.recommendations = payload.recommendations;
    if (payload.bestSeason !== undefined) model.bestSeason = payload.bestSeason;
    if (payload.recommendedDays !== undefined) model.recommendedDays = payload.recommendedDays;
    if (payload.attractions !== undefined) {
      model.attractions = Array.isArray(payload.attractions)
        ? JSON.stringify(payload.attractions)
        : payload.attractions;
    }

    return model;
  }

  // 出库数据转换
  toDTO(city) {
    const plain = city.toJSON();
    return {
      id: plain.id,
      name: plain.name,
      description: plain.description,
      image: plain.image,
      tags: safeParseArray(plain.tags),
      rating: plain.rating,
      views: plain.views,
      recommendations: plain.recommendations,
      bestSeason: plain.bestSeason,
      recommendedDays: plain.recommendedDays,
      attractions: safeParseArray(plain.attractions),
      created_at: plain.created_at,
      updated_at: plain.updated_at,
    };
  }
}

function safeParseArray(str) {
  if (!str) return [];
  try {
    const val = JSON.parse(str);
    return Array.isArray(val) ? val : [];
  } catch {
    return [];
  }
}

module.exports = CityService;